/*
 * SliderDelegate.cpp  0.4.0 / Dec 05, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the LGPL version 2.1 license.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#include "SliderDelegate.h"

// SliderDelegate Class. -------------------------------------------------------

/*!
 * \brief Constructs new SliderDelegate object.
 *
 * \param env the JNIEnv pointer
 * \param obj Slider java object
 */
SliderDelegate::SliderDelegate(JNIEnv *env, jobject obj)
  : ComponentDelegate(env, obj, new QSlider(Qt::Horizontal))
{
  qSlider()->setMaximum(100);
  qSlider()->setValue(50);
  qSlider()->setTickInterval(10);
  qSlider()->setTickPosition(QSlider::NoTicks);
  connectDirect(qSlider(), SIGNAL(valueChanged(int)),
                SLOT(valueChangedSlot(int)));
  connectDirect(qSlider(), SIGNAL(sliderPressed()),
                SLOT(sliderPressedSlot()));
  connectDirect(qSlider(), SIGNAL(sliderReleased()),
                SLOT(sliderReleasedSlot()));
}

// SliderDelegate :: Native Calls. ---------------------------------------------

/*!
 * \brief Sets slider model.
 *
 * \param env the JNIEnv pointer
 * \param minimum the minimum slider value
 * \param maximum the maximum slider value
 * \param value the slider value
 */
void SliderDelegate::setModel(JNIEnv *env, jint minimum, jint maximum,
                              jint value)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setModel, SWING_ENV_ARG, JINT_ARG(minimum), JINT_ARG(maximum),
                  JINT_ARG(value))
  qSlider()->setRange(minimum, maximum);
  qSlider()->setValue(value);
}

/*!
 * \brief Sets slider value.
 *
 * \param env the JNIEnv pointer
 * \param value the slider value
 */
void SliderDelegate::setValue(JNIEnv *env, jint value)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setValue, SWING_ENV_ARG, JINT_ARG(value))
  qSlider()->setValue(value);
}

/*!
 * \brief Sets minimum slider value.
 *
 * \param env the JNIEnv pointer
 * \param minimum the minimum slider value
 */
void SliderDelegate::setMinimum(JNIEnv *env, jint minimum)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setMinimum, SWING_ENV_ARG, JINT_ARG(minimum))
  qSlider()->setMinimum(minimum);
}

/*!
 * \brief Sets maximum slider value.
 *
 * \param env the JNIEnv pointer
 * \param maximum the maximum slider value
 */
void SliderDelegate::setMaximum(JNIEnv *env, jint maximum)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setMaximum, SWING_ENV_ARG, JINT_ARG(maximum))
  qSlider()->setMaximum(maximum);
}

/*!
 * \brief Sets slider orientation.
 *
 * \param env the JNIEnv pointer
 * \param orientation the orientation
 */
void SliderDelegate::setOrientation(JNIEnv *env, jint orientation)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setOrientation, SWING_ENV_ARG, JINT_ARG(orientation))
  switch(orientation) {
    case 0:
      qSlider()->setOrientation(Qt::Horizontal);
      break;
    case 1:
      qSlider()->setOrientation(Qt::Vertical);
      break;
  }
}

/*!
 * \brief Sets tick position.
 *
 * \param env the JNIEnv pointer
 * \param tickPosition the tick position
 */
void SliderDelegate::setTickPosition(JNIEnv *env, jint tickPosition)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setTickPosition, SWING_ENV_ARG, JINT_ARG(tickPosition))
  qSlider()->setTickPosition(QSlider::TickPosition(tickPosition));
}

/*!
 * \brief Sets tick spacing
 *
 * \param env the JNIEnv pointer
 * \param tickSpacing the tick spacing
 */
void SliderDelegate::setTickSpacing(JNIEnv *env, jint tickSpacing)
{
  Q_ASSERT(env);
  SWING_REENTRANT(setTickSpacing, SWING_ENV_ARG, JINT_ARG(tickSpacing))
  qSlider()->setTickInterval(tickSpacing);
}

// SliderDelegate :: Static Native Calls. --------------------------------------

/*!
 * \brief Initializes the SliderDelegate class.
 *
 * \param env the JNIEnv pointer
 * \param cls the Slider java class
 *
 * \exception FatalError if failed
 */
void SliderDelegate::initialize(JNIEnv *env, jclass cls)
{
  Q_ASSERT(env);
  Q_ASSERT(cls);
  Q_ASSERT(!sm_valueChangedMID);
  if (!INIT_UMID(valueChanged, cls, "(I)V") ||
      !INIT_UMID(valueIsAdjusting, cls, "(Z)V")) {
    FATAL_LOGGED_ERROR("SliderDelegate initialization failed");
  }
}

/*!
 * \brief Returns new instance of the delegate object
 *
 * \param env the JNIEnv pointer
 * \param obj the Swing object
 * 
 * \return new instance of the delegate object
 */
jlong SliderDelegate::newInstance(JNIEnv *env, jobject obj)
{
  if (JNISwingWrapper::isSwingThread(env)) {
    return reinterpret_cast<jlong>(new SliderDelegate(env, obj));
  }
  return SwingUtilitiesDelegate::invokeLongAndWait(env, obj, createMID());
}

// SliderDelegate :: Native Callbacks. -----------------------------------------

/*!
 * \brief Calls \c valueChanged method of the ScrollBar java object.
 *
 * \param value the changed value
 */
void SliderDelegate::valueChanged(jint value)
{
  jniObject()->callVoidMethod(sm_valueChangedMID, value);
}

/*!
 * \brief Calls \c valueIsAdjusting method of the ScrollBar java object.
 *
 * \param adjusting \c true if adjusting
 */
void SliderDelegate::valueIsAdjusting(jboolean adjusting)
{
  jniObject()->callVoidMethod(sm_valueIsAdjustingMID, adjusting);
}

// SliderDelegate :: Protected Member Functions. -------------------------------

/*!
 * \brief \c valueChanged slot.
 *
 * \param value the value
 */
void SliderDelegate::valueChangedSlot(int value)
{
  valueChanged(value);
}

/*!
 * \brief \c sliderPressed slot.
 */
void SliderDelegate::sliderPressedSlot()
{
  valueIsAdjusting(true);
}

/*!
 * \brief \c sliderReleased slot.
 */
void SliderDelegate::sliderReleasedSlot()
{
  valueIsAdjusting(false);
}

// SliderDelegate :: Private Static Data Members. ------------------------------

jmethodID SliderDelegate::sm_valueChangedMID = 0;
jmethodID SliderDelegate::sm_valueIsAdjustingMID = 0;
